<template>
    <div>
        <canvas ref="canvasRef" width="500" height="500"></canvas>
    </div>
</template>
    
<script setup lang='ts'>
import { ref, onMounted } from 'vue'
import * as GLMat from 'gl-matrix'
console.log(GLMat);
const canvasRef = ref<HTMLCanvasElement>()

const renderLine = () => {
    if (!canvasRef.value) return
    const webgl = canvasRef.value?.getContext('webgl') as WebGLRenderingContext;
    // 视图范围
    webgl.viewport(0, 0, canvasRef.value.clientWidth, canvasRef.value.clientHeight);
    // 坐标系转换关系
    const projMa4 = GLMat.mat4.create()
    GLMat.mat4.ortho(projMa4, 0, canvasRef.value.clientWidth, canvasRef.value.clientHeight, 0, -1.0, 1.0)

    // 着色器
    // 顶点着色器
    const vertexString = `
        // 用于接受js传递来的点的位置参数;
        attribute vec4 a_position;
        // 着色器中的坐标系
        uniform mat4 proj;
        void main(void){
            gl_Position = proj * a_position;
            gl_PointSize  = 2.0;
        }
    
    `
    // 片元着色器
    const fragmentString = `
     void main(void){
        gl_FragColor  = vec4(1.0,0,0,1.0);
     }
    `
    // shader
    const vsShader = webgl.createShader(webgl.VERTEX_SHADER);
    const fsShader = webgl.createShader(webgl.FRAGMENT_SHADER)
    if (!vsShader || !fsShader) return
    webgl.shaderSource(vsShader, vertexString);
    webgl.shaderSource(fsShader, fragmentString)


    // 编译
    webgl.compileShader(vsShader);
    webgl.compileShader(fsShader)

    // if (!webgl.getShaderParameter(vsShader, webgl.COMPILE_STATUS)) {
    //     var err = webgl.getShaderInfoLog(vsShader);
    //     alert(err);
    //     return;
    // }
    // if (!webgl.getShaderParameter(fsShader, webgl.COMPILE_STATUS)) {
    //     var err = webgl.getShaderInfoLog(fsShader);
    //     alert(err);
    //     return;
    // }


    // 创建着色器程序 由两个编译过后的 WebGLShader 组成 - 顶点着色器和片段着色器
    const program = webgl.createProgram();
    if (!program) return;
    webgl.attachShader(program, vsShader)
    webgl.attachShader(program, fsShader)

    // 使用着色器程序
    webgl.linkProgram(program);
    webgl.useProgram(program);



    // 获取着色器变量赋值
    const uniformLocartion = webgl.getUniformLocation(program, 'proj');
    if (!uniformLocartion) return;
    webgl.uniformMatrix4fv(uniformLocartion, false, projMa4)


    webgl.clearColor(0, 0, 0, 1)
    webgl.clear(webgl.COLOR_BUFFER_BIT) // 颜色缓冲区

    /// 
    // 进行数据绑定  a_position 定义在顶点着色器中的变量
    const a_point_handler = webgl.getAttribLocation(program, 'a_position');
    let drag = false
    const points: number[] = [];
    canvasRef.value.addEventListener('mousedown', () => { drag = true })
    canvasRef.value.addEventListener('mousemove', (event: MouseEvent) => {
        if (!drag) return
        points.push(event.offsetX, event.offsetY, 0)
        // 缓冲区设置
        const datas = new Float32Array(points);
        const pointbuffer = webgl.createBuffer();
        webgl.bindBuffer(webgl.ARRAY_BUFFER, pointbuffer);
        webgl.bufferData(webgl.ARRAY_BUFFER, datas, webgl.STATIC_DRAW)

        webgl.enableVertexAttribArray(a_point_handler)
        webgl.vertexAttribPointer(a_point_handler, 3, webgl.FLOAT, false, datas.BYTES_PER_ELEMENT * 3, 0);
        webgl.clearColor(0, 0, 0, 1)
        // 清空缓存
        webgl.clear(webgl.COLOR_BUFFER_BIT) // 颜色缓冲区
        webgl.drawArrays(webgl.LINE_STRIP, 0, points.length / 3)

    })
    canvasRef.value.addEventListener('mouseup', () => drag = false)
    canvasRef.value.addEventListener('mouseleave', () => drag = false)
}




onMounted(() => {
    renderLine()
})
</script>
    
<style></style>